<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSON utils benchmark</title>
<link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap/4.6.1/css/bootstrap.css" type="text/css" rel="stylesheet" />
<link rel="stylesheet" href="./index.css">

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.7.1.min.js"  ></script>
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap/4.6.1/js/bootstrap.bundle.min.js" type="application/javascript"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body>

<figure class="highcharts-figure">
    <div id="parent-container">
		<div id="container"></div>
	</div>
</figure>
<!-- Modal -->
<div class="modal fade" id="jsonUtilModal" tabindex="-1" aria-labelledby="jsonUtilModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-xl">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
       <div class="container-fluid">
      <div class="row">
		<div class="col-xl-12 text-center">
			<img class="avatar"/>
			<h3 class="jsonUtilName" ></h3>
			<div style="text-align: left;margin-left: 20px">
				<h6  >Score: <span class="jsonUtilScore"></span></h6>
				<h6  >Memory Usage: <span class="minMem"></span> ~ <span class="maxMem"></span></h6>
				<h6  >Cpu Usage: <span class="minCpu"></span> ~ <span class="maxCpu"></span></h6>
				<h6  >Max Total Memory: <span class="totalMem"></span></h6>
			</div>
		</div>
      </div>
      <div class="row">
        <div class="col-xl-12">
        <div id="jsonUtilChartContainer" ></div>
        </div>
      </div>
      </div>
      </div>
      </div>
    </div>
  </div>
</div>
<script type="text/javascript">
const benchmarks = #{benchmarks};
const memAndCpuUsages = #{memAndCpuUsages};
for(let util in memAndCpuUsages){
	memAndCpuUsages[util]["messages"].forEach(item=>{
	item["usedMem"] = item["totalMem"]-item["freeMem"];
	});
}
const jsonUtilsAvatars ={
	"jackson":"https://avatars.githubusercontent.com/u/382692",
	"jacksonSingleton":"https://avatars.githubusercontent.com/u/382692",
	"fastjson2":"https://user-images.githubusercontent.com/1063891/233821110-0c912009-4de3-4664-a27e-25274f2fa9c1.jpg",
	"avaje":"https://github.com/avaje/.github/raw/main/profile/logo.svg",
	"avajeSingleton":"https://github.com/avaje/.github/raw/main/profile/logo.svg",
	"dsl":"https://docs.dsl-platform.com/static/img/how-dsl-works-1.png",
	"dslSingleton":"https://docs.dsl-platform.com/static/img/how-dsl-works-1.png",
	"gson":"https://avatars.githubusercontent.com/u/1342004",
	"gsonSingleton":"https://avatars.githubusercontent.com/u/1342004",
	"jsonInJava":"https://github.com/stleary/JSON-java/raw/master/images/JsonJava.png?raw=true",
	"jsonlib":"https://json-lib.sourceforge.net/images/json-lib.png",
	"jodd": "https://jodd.org/android-icon-192x192.png"
	

};
Highcharts.AST.allowedReferences.push('javascript:');
function showJSONUtilChart(jsonUtilName){
	const jsonUtilBenchmark = benchmarks.find(b=>b["benchmarkName"].indexOf(jsonUtilName+"Test")>-1);
	const jsonUtilMemAndCpuUsages = memAndCpuUsages.find(b=>b["jsonUtil"]==jsonUtilName).messages;
	$("#jsonUtilModalLabel").html(jsonUtilName+"&nbsp;<span style='font-size: 0.8em'>"+jsonUtilBenchmark["score"]+"</span>");
	console.log(jsonUtilName, jsonUtilMemAndCpuUsages);
	let avatar ="https://www.json.org/img/json160.gif";
	if(!!jsonUtilsAvatars[jsonUtilName] ){
		avatar = jsonUtilsAvatars[jsonUtilName];
	}	
	
	$("#jsonUtilModal .avatar").attr("src",avatar);
	$("#jsonUtilModal .jsonUtilName").text(jsonUtilName);
	$("#jsonUtilModal .jsonUtilScore").text(jsonUtilBenchmark["score"].toFixed(2)+" ms/op");
	// mem
	jsonUtilMemAndCpuUsages.sort((a,b)=>a["usedMem"]-b["usedMem"]);
	$("#jsonUtilModal .minMem").text((jsonUtilMemAndCpuUsages[0]["usedMem"]/1024/1024).toFixed(2)+" MB");
	$("#jsonUtilModal .maxMem").text((jsonUtilMemAndCpuUsages[jsonUtilMemAndCpuUsages.length-1]["usedMem"]/1024/1024).toFixed(2)+" MB");
	jsonUtilMemAndCpuUsages.sort((a,b)=>b["totalMem"]-a["totalMem"]);
	$("#jsonUtilModal .totalMem").text((jsonUtilMemAndCpuUsages[0]["totalMem"]/1024/1024).toFixed(2)+" MB");
	// cpu
	jsonUtilMemAndCpuUsages.sort((a,b)=>a["cpuPercent"]-b["cpuPercent"]);
	$("#jsonUtilModal .minCpu").text((jsonUtilMemAndCpuUsages[0]["cpuPercent"]).toFixed(2)+" %");
	$("#jsonUtilModal .maxCpu").text((jsonUtilMemAndCpuUsages[jsonUtilMemAndCpuUsages.length-1]["cpuPercent"]).toFixed(2)+" %");
	
	jsonUtilMemAndCpuUsages.sort((a,b)=>a["time"]-b["time"]);
	Highcharts.chart('jsonUtilChartContainer', {
			chart: {
				height: 300
			},
			title: {
				text:null
			},
		  xAxis: {
		        type: 'datetime',
		        crosshair: true
		  },
		  legend: {
			  enabled: false
		  },
		  credits: {
			  enabled: false
		  },
		  tooltip: {
			  shared: true  
		  },
		  yAxis: [{
			  title: {
			      text: 'Times'
			  }
		  },{
			 opposite: true,
			 title: {
			      text: 'MemoryUsage'
			  }
		  },{
			 opposite: true,
			 title: {
			      text: 'CpuUsage'
			  }
		  }],
		series: [{
			type: "area",
			name: "Times",
			color: "limegreen",
			yAxis: 0,
			data: jsonUtilMemAndCpuUsages.map(item=>{
				return [item["time"], item["finished"]];
			})
			
		},{
			type: "area",
			name: "MemoryUsage",
			color: "#ff6c0e",
			yAxis: 1,
			data: jsonUtilMemAndCpuUsages.map(item=>{
				return [item["time"], item["totalMem"] - item["freeMem"]];
			})
			
		},{
			type: "line",
			name: "CpuUsage",
			yAxis: 2,
			data: jsonUtilMemAndCpuUsages.map(item=>{
				return [item["time"], item["cpuPercent"]];
			})
			
		}]
		
	},function(){
		
		$("#jsonUtilModal").modal('show');
	});
}
$(document).ready(function(){
	
	Highcharts.chart('container', {
	    chart: {
	        type: 'bar'
	    },
	    title: {
	        text: 'JSON utils benchmark'
	    },
	    subtitle: {
	        text: 'less is better'
	    },
	    xAxis: {
	    	 type: 'category',
	        title: {
	            text: null
	        },
	        labels: {
		        formatter: function () {
		        	const label = this.value.substring(0, 1).toUpperCase() + this.value.substring(1);
		            return "<a href='javascript:showJSONUtilChart(\""+this.value+"\")' style='font-size: 1.2em'><b>"+label+"</b></a>";
		        }
	        },
	        gridLineWidth: 1,
	        lineWidth: 0
	    },
	    yAxis: {
	        min: 0,
	        title: {
	            text: 'Score (ms/op)',
	            align: 'high'
	        },
	        opposite: true,
	        labels: {
	            overflow: 'justify'
	        },
	        gridLineWidth: 0
	    },
	    tooltip: {
	        valueSuffix: ' ms/op'
	    },
	    plotOptions: {
	        bar: {
	            borderRadius: '50%',
	            colorByPoint: true,
	            dataLabels: {
	                enabled: true
	            },
	            groupPadding: 0.1
	        }
	    },
	    legend: {
	        enabled: false
	    },
	    credits: {
	        enabled: false
	    },
	    series: [{
			name: "Score",
			data:benchmarks.sort((a, b) => a.score - b.score)
				.map(benchmark =>{
					const label = benchmark.benchmarkName.replace("json.JSONUtilsBenchmark.","").replace("Test","");
					const score = Math.round(benchmark.score*100)/100;
					return [label, score]
				})
	    }]
	});
});

</script>
</body>
</html>